// Author	: damphat@gmail.com
// Created	: 01/12/2008

#pragma once
#include "vn/NetCommon.h"
#include "vn/EndPoint.h"
#include "vn/IPAddress.h"


NET_BEGIN

class IPEndPoint : public EndPoint {
public:
	IPEndPoint(int family = AF_INET) {
		memset(&m_data, 0, sizeof(m_data));
		m_data.v4.sin_family = family;
	}

	IPEndPoint(const IPAddress &ip, int port) {
		CHECK_ARG((ip.GetAddressFamily() == AF_INET ) ||
				  (ip.GetAddressFamily() == AF_INET6) );
		CHECK_ARG_RANGE_PORT(port);

		memset(&m_data, 0, sizeof(m_data));

		if (ip.GetAddressFamily() == AF_INET) {
			m_data.v4.sin_family = AF_INET;
			m_data.v4.sin_addr.S_un.S_addr = *(u_long*)ip.GetData();
			m_data.v4.sin_port = htons(port);
		}
		else if (ip.GetAddressFamily() == AF_INET6) {
			assert(false);// how
		}
	}

	virtual short GetAddressFamily() const {
		return m_data.v4.sin_family; // v4 same location with v6
	}

	virtual LPCChar GetData() const {
		return (LPCChar)&m_data;
	}

	virtual LPChar GetData() {
		return (LPChar)&m_data;
	}

	virtual int GetLength() const {
		if (GetAddressFamily() == AF_INET){
			return sizeof(m_data.v4);
		}
// cfree
//		else if(GetAddressFamily() == AF_INET6) {
//			return sizeof(m_data.v6);
//		}
		assert(false);
		return -1;
	}

	virtual ~IPEndPoint() {
	}

private:
	union {
		sockaddr_in v4;
		// cfree
		//sockaddr_in6 v6;
	} m_data;
};

NET_END

//
// sockaddr_in
// sockaddr_in6
// note: we overridden two method derived from class EndPoint.
// can we remove GetData and GetLength methods from implementation?
// DotNet IPEndPoint allow to get and set address and port?
// Does IPv6 have notion of port?
